from django.contrib.auth.models import Group, Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import render
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated

from .permissions import HasModelPermission, clear_permission_cache, require_permissions, get_or_create_staff_group
from .decorators import action_permission, register_action_permission
from .serializers import (
    EmptySerializer,
    GroupSerializer,

    PermissionSerializer,
    ResetPasswordSerializer,
    UserDetailSerializer,
    UserSerializer,
    ChangePasswordSerializer,
)
from core.serializers import MessageResponseSerializer
# Create your views here.

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [HasModelPermission]
    
    filterset_fields = ['username', 'email', 'is_active', 'is_staff', 'groups']
    search_fields = ['username', 'email', 'first_name', 'last_name']
    ordering_fields = ['username', 'email', 'date_joined']

    def get_serializer_class(self):
        """
        根据不同的动作返回不同的序列化器
        """
        if self.action == 'me':
            return UserDetailSerializer
        if self.action == 'reset_password':
            return ResetPasswordSerializer
        if self.action == 'change_password':
            return ChangePasswordSerializer
        return self.serializer_class

    def perform_create(self, serializer):
        """
        创建用户时，如果是员工则自动加入员工组
        """
        user = serializer.save()
        if user.is_staff:
            staff_group = get_or_create_staff_group()
            user.groups.add(staff_group)

    def perform_update(self, serializer):
        """
        更新用户时，处理员工组的分配
        """
        # 获取更新前的 is_staff 状态
        instance = self.get_object()
        was_staff = instance.is_staff
        
        # 保存更新
        user = serializer.save()
        
        # 获取更新后的 is_staff 状态
        is_staff = user.is_staff
        
        # 如果 is_staff 状态发生变化
        if was_staff != is_staff:
            staff_group = get_or_create_staff_group()
            
            if is_staff:
                # 如果变成员工，添加到员工组
                user.groups.add(staff_group)
            else:
                # 如果不再是员工，从员工组移除
                user.groups.remove(staff_group)
            
            # 清除权限缓存
            clear_permission_cache(user.id)

    @action_permission(methods=['GET'], detail=False, permission_classes=[IsAuthenticated],
                      permission_description="Can view own user information")
    def me(self, request):
        """
        获取当前登录用户的信息
        """
        serializer = self.get_serializer(request.user)
        return Response(serializer.data)

    @action_permission(methods=['GET'], detail=True,
                      permission_description="Can view user groups")
    def groups(self, request, pk=None):
        """
        获取指定用户的所有角色
        """
        user = self.get_object()
        groups = user.groups.all()
        serializer = GroupSerializer(groups, many=True)
        return Response(serializer.data)

    @action_permission(methods=['POST'], detail=False, permission_classes=[IsAuthenticated],
                      permission_description="Can reset own password")
    def reset_password(self, request):
        """
        重置当前用户的密码
        """
        user = request.user
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        
        user.set_password(serializer.validated_data['new_password'])
        user.save()
        
        return Response({'message': '密码重置成功'})

    @extend_schema(
        summary="修改当前用户密码",
        description="修改当前登录用户的密码，需要提供旧密码和新密码",
        responses={
            200: MessageResponseSerializer,
            400: OpenApiTypes.OBJECT,
            401: OpenApiTypes.OBJECT,
        },
    )
    @action(detail=False, methods=['post'], permission_classes=[IsAuthenticated])
    def change_password(self, request):
        """
        修改当前用户的密码
        """
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({'detail': '密码修改成功'}, status=status.HTTP_200_OK)

class GroupViewSet(viewsets.ModelViewSet):
    """
    角色管理视图集
    """
    queryset = Group.objects.all()
    serializer_class = GroupSerializer
    permission_classes = [HasModelPermission]
    filterset_fields = ['name']
    search_fields = ['name']
    ordering_fields = ['name']

    def perform_update(self, serializer):
        instance = serializer.save()
        # 清除相关用户的权限缓存
        for user in instance.user_set.all():
            clear_permission_cache(user.id)

    @extend_schema(
        request=EmptySerializer,
        responses={200: MessageResponseSerializer, 403: MessageResponseSerializer, 404: MessageResponseSerializer}
    )
    @register_action_permission("Can add users to group")
    @action(methods=['post'], detail=True)
    def add_users(self, request, pk=None):
        """添加用户到角色"""
        group = self.get_object()
        user_ids = request.data.get('user_ids', [])
        
        if not user_ids:
            return Response({"error": "No user IDs provided"}, status=status.HTTP_400_BAD_REQUEST)
            
        users = User.objects.filter(id__in=user_ids)
        group.user_set.add(*users)
        
        # 清除所有相关用户的权限缓存
        for user_id in user_ids:
            clear_permission_cache(user_id)
            
        return Response({"message": "Users added successfully"})

    @extend_schema(
        request=EmptySerializer,
        responses={200: MessageResponseSerializer}
    )
    @register_action_permission("Can remove users from group")
    @action(methods=['post'], detail=True)
    def remove_users(self, request, pk=None):
        """从角色中移除用户"""
        group = self.get_object()
        user_ids = request.data.get('user_ids', [])
        
        if not user_ids:
            return Response({"error": "No user IDs provided"}, status=status.HTTP_400_BAD_REQUEST)
            
        users = User.objects.filter(id__in=user_ids)
        group.user_set.remove(*users)
        
        # 清除所有相关用户的权限缓存
        for user_id in user_ids:
            clear_permission_cache(user_id)
            
        return Response({"message": "Users removed successfully"})

class PermissionViewSet(viewsets.ReadOnlyModelViewSet):
    """
    权限管理视图集
    
    只提供只读操作，因为权限是由系统自动创建的，不应该手动修改
    """
    queryset = Permission.objects.select_related('content_type').all()
    serializer_class = PermissionSerializer
    permission_classes = [HasModelPermission]
    filterset_fields = ['codename', 'content_type__app_label', 'content_type__model']
    search_fields = ['name', 'codename']
    ordering_fields = ['id', 'name', 'codename']

    def get_queryset(self):
        """
        可以根据 app_label 和 model 过滤权限
        """
        queryset = super().get_queryset()
        app_label = self.request.query_params.get('app_label', None)
        model = self.request.query_params.get('model', None)

        if app_label:
            queryset = queryset.filter(content_type__app_label=app_label)
        if model:
            queryset = queryset.filter(content_type__model=model)

        return queryset

    @action_permission(methods=['GET'], detail=False,
                      permission_description="Can view available permissions")
    def available_permissions(self, request):
        """
        获取可用的权限列表，按应用和模型分组
        """
        queryset = self.get_queryset()
        
        # 按应用和模型分组
        grouped_permissions = {}
        for perm in queryset:
            app_label = perm.content_type.app_label
            model = perm.content_type.model
            
            if app_label not in grouped_permissions:
                grouped_permissions[app_label] = {}
                
            if model not in grouped_permissions[app_label]:
                grouped_permissions[app_label][model] = []
                
            grouped_permissions[app_label][model].append({
                'id': perm.id,
                'name': perm.name,
                'codename': perm.codename
            })
        
        return Response(grouped_permissions)
